home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Networking / JSaver / Source / NewAppletDialog.cp < prev    next >
Encoding:
Text File  |  1997-06-05  |  16.5 KB  |  722 lines  |  [TEXT/CWIE]

  1. /*
  2.  * NewAppletDialog.cp
  3.  */
  4.  
  5. #include "NewAppletDialog.h"
  6. #include "StringListResource.h"
  7.  
  8. const cAppletDialog = 1129;
  9. const cAddEditDialog = 1130;
  10.  
  11. enum AppletItems {
  12.     eAddItem = 3,
  13.     eChooseLabel,
  14.     eListArea,
  15.     eURLArea,
  16.     eEditButton,
  17.     eDeleteButton,
  18.     eRandomCheckbox
  19. };
  20.  
  21. enum AddEditItems {
  22.     eNameLabel = 3,
  23.     eURLLabel,
  24.     eNameText,
  25.     eURLText
  26. };
  27.  
  28. struct FontSaver {
  29.     short saveFace, saveSize, saveFont;
  30. };
  31.  
  32. static void setupDialogFont(DialogPtr dialog, short fontSize, FontSaver* saver)
  33. {
  34.     SetPort(dialog);
  35.     TextFont(geneva);
  36.     TextFace(normal);
  37.     TextSize(fontSize);
  38.     saver->saveFont = dialog->txFont;
  39.     saver->saveSize = dialog->txSize;
  40.     saver->saveFace = dialog->txFace;
  41. }
  42.  
  43. static void restoreDialogFont(FontSaver* saver)
  44. {
  45.     TextFont(saver->saveFont);
  46.     TextFace(saver->saveFace);
  47.     TextSize(saver->saveSize);
  48. }
  49.  
  50. /*
  51.  * doAddDialog
  52.  */
  53.  
  54. static void setEditTextItem(DialogPtr dialog, int ixItem, Str255 text)
  55. {
  56.     short itemType;
  57.     Rect itemRect;
  58.     Handle itemHandle;
  59.     GetDItem(dialog, ixItem, &itemType, &itemHandle, &itemRect);
  60.     SetIText(itemHandle, text);
  61. }
  62.  
  63. static void getEditTextItem(DialogPtr dialog, int ixItem, Str255 text)
  64. {
  65.     short itemType;
  66.     Rect itemRect;
  67.     Handle itemHandle;
  68.     GetDItem(dialog, ixItem, &itemType, &itemHandle, &itemRect);
  69.     GetIText(itemHandle, text);
  70. }
  71.  
  72. static Boolean doAddDialog(Str255 itemLabel, Str255 itemURL)
  73. {
  74.     Boolean result = false;
  75.     DialogPtr dialog = GetNewDialog(cAddEditDialog, nil, WindowPtr(-1));
  76.     if (dialog) {
  77.         SetDialogDefaultItem(dialog, ok);
  78.         SetDialogCancelItem(dialog, cancel);
  79.         SetDialogTracksCursor(dialog, true);
  80.         
  81.         setEditTextItem(dialog, eNameText, itemLabel);
  82.         setEditTextItem(dialog, eURLText, itemURL);    
  83.         SelIText(dialog, eNameText, 0, 32767);
  84.         
  85.         short itemHit;
  86.         Boolean continueLoop = true;
  87.         
  88.         ShowWindow(dialog);
  89.         
  90.         do {
  91.             ModalDialog(nil, &itemHit);
  92.             
  93.             switch (itemHit) {
  94.                 case ok:
  95.                     continueLoop = false;
  96.                     getEditTextItem(dialog, eNameText, itemLabel);
  97.                     getEditTextItem(dialog, eURLText, itemURL);
  98.                     result = true;
  99.                     break;
  100.                 
  101.                 case cancel:
  102.                     continueLoop = false;
  103.                     break;
  104.                 
  105.                 case eNameLabel:
  106.                     SelIText(dialog, eNameText, 0, 32767);
  107.                     break;
  108.                 
  109.                 case eURLLabel:
  110.                     SelIText(dialog, eURLText, 0, 32767);
  111.                     break;
  112.             }
  113.         } while (continueLoop);        
  114.         
  115.         DisposeDialog(dialog);
  116.     }
  117.     return result && itemLabel[0] > 0 && itemURL[0] > 0;
  118. }
  119.  
  120. /*
  121.  * newAppletDialog
  122.  */
  123.  
  124. static ListHandle theList;
  125. static UserItemUPP theListUPP = nil;
  126. static UserItemUPP theURLUPP = nil;
  127.  
  128. static Handle theLabelTexts;
  129. static Handle theURLTexts;
  130. static long theCurrentItem = 0;
  131. static Boolean theRandomSet;
  132.  
  133. static void selectItem(int ixCell)
  134. {
  135.     Cell cell = { 0, 0 };
  136.     while (LGetSelect(true, &cell, theList)) {    
  137.         LSetSelect(false, cell, theList);
  138.     }
  139.     cell.v = ixCell;
  140.     LSetSelect(true, cell, theList);
  141.     LAutoScroll(theList);
  142. }
  143.  
  144. static void addToList(Str255 itemLabel, Str255 itemURL)
  145. {
  146.     Cell cell;
  147.     cell.h = 0;
  148.     cell.v = LAddRow(1, -1, theList);
  149.     LSetCell(&itemLabel[1], itemLabel[0], cell, theList);
  150.     PtrAndHand(itemLabel, theLabelTexts, 256);
  151.     PtrAndHand(itemURL, theURLTexts, 256);
  152.     selectItem(cell.v);
  153. }
  154.  
  155. static void getCurrentItem(StringPtr itemLabel, StringPtr itemURL)
  156. {
  157.     if (theCurrentItem == -1) {
  158.         if (itemLabel != nil)
  159.             itemLabel[0] = 0;
  160.         if (itemURL != nil)
  161.             itemURL[0] = 0;
  162.     } else {
  163.         if (itemLabel)
  164.             BlockMoveData(*theLabelTexts + (256 * theCurrentItem), itemLabel, 256);
  165.         if (itemURL)
  166.             BlockMoveData(*theURLTexts + (256 * theCurrentItem), itemURL, 256);
  167.     }
  168. }
  169.  
  170. static void updateURLArea(DialogPtr dialog, Boolean justDoIt)
  171. {
  172.     Cell cell = { 0, 0 };
  173.     short newIndex;
  174.  
  175.     if (! LGetSelect(true, &cell, theList))
  176.         newIndex = -1;
  177.     else
  178.         newIndex = cell.v;
  179.         
  180.     if (newIndex != theCurrentItem || justDoIt) {
  181.         short itemType;
  182.         Rect itemRect;
  183.         Handle itemHandle;
  184.         GetDItem(dialog, eURLArea, &itemType, &itemHandle, &itemRect);
  185.         InsetRect(&itemRect, 1, 1);
  186.         InvalRect(&itemRect);
  187.     }
  188.     theCurrentItem = newIndex;
  189. }
  190.  
  191. static void deleteCurrentItem(DialogPtr dialog)
  192. {
  193.     if (theCurrentItem != -1) {
  194.         Munger(theLabelTexts, (256 * theCurrentItem), nil, 256, Ptr(-1), 0);
  195.         Munger(theURLTexts, (256 * theCurrentItem), nil, 256, Ptr(-1), 0);
  196.  
  197.         Cell cell;
  198.         cell.h = 0;
  199.         cell.v = theCurrentItem;
  200.         LDelRow(1, theCurrentItem, theList);
  201.         theCurrentItem--;
  202.         if (theCurrentItem < 0)
  203.             theCurrentItem = 0;
  204.         selectItem(theCurrentItem);
  205.         updateURLArea(dialog, true);
  206.     }
  207. }
  208.  
  209. static void setCurrentItem(DialogPtr dialog, StringPtr itemLabel, StringPtr itemURL)
  210. {
  211.     Cell cell;
  212.     
  213.     cell.h = 0;
  214.     cell.v = theCurrentItem;
  215.  
  216.     LSetCell(&itemLabel[1], itemLabel[0], cell, theList);
  217.  
  218.     BlockMoveData(itemLabel, *theLabelTexts + (256 * theCurrentItem), 256);
  219.     BlockMoveData(itemURL, *theURLTexts + (256 * theCurrentItem), 256);
  220.  
  221.     updateURLArea(dialog, true);
  222. }
  223.  
  224. static pascal void _ListProc(DialogPtr dialog, short itemNumber)
  225. {
  226.     short itemType;
  227.     Rect itemRect;
  228.     Handle itemHandle;
  229.     GetDItem(dialog, itemNumber, &itemType, &itemHandle, &itemRect);
  230.  
  231.     FontSaver saver;
  232.     setupDialogFont(dialog, 12, &saver);
  233.  
  234.     MoveTo(itemRect.right, itemRect.top - 1);
  235.     LineTo(itemRect.left, itemRect.top - 1);
  236.     LineTo(itemRect.left, itemRect.bottom);
  237.     LineTo(itemRect.right, itemRect.bottom);
  238.     LUpdate(dialog->visRgn, theList);
  239.  
  240.     restoreDialogFont(&saver);
  241. }
  242.  
  243. static pascal void _URLProc(DialogPtr dialog, short itemNumber)
  244. {
  245.     short itemType;
  246.     Rect itemRect;
  247.     Handle itemHandle;
  248.     GetDItem(dialog, itemNumber, &itemType, &itemHandle, &itemRect);
  249.     FontSaver saver;
  250.     setupDialogFont(dialog, 9, &saver);
  251.     FrameRect(&itemRect);
  252.     InsetRect(&itemRect, 1, 1);
  253.     EraseRect(&itemRect);
  254.     MoveTo(itemRect.left + 2, itemRect.bottom - 3);
  255.     Str255 url;
  256.     getCurrentItem(nil, url);
  257.     DrawString(url);
  258.     restoreDialogFont(&saver);
  259. }
  260.  
  261. static void setupUserItems(DialogPtr dialog)
  262. {
  263.     /*
  264.      * Others...
  265.      */
  266.      
  267.     short itemType;
  268.     Rect itemRect;
  269.     Handle itemHandle;
  270.     
  271.     FontSaver saver;
  272.     setupDialogFont(dialog, 12, &saver);
  273.  
  274.     /*
  275.      * List
  276.      */
  277.     GetDItem(dialog, eListArea, &itemType, &itemHandle, &itemRect);
  278.     
  279.     Rect rBounds = { 0, 0, 0, 1 };
  280.     Point cellBounds = { 0, 0 };
  281.     Rect listRect;
  282.     listRect = itemRect;
  283.     listRect.left += 1;
  284.     listRect.right -= 16;
  285.     theList = LNew(&listRect, &rBounds, cellBounds, 0, dialog, false, false, false, true);
  286.     (**theList).selFlags = lOnlyOne;
  287.     
  288.     if (theListUPP == nil)
  289.         theListUPP = NewUserItemProc(_ListProc);
  290.  
  291.     SetDItem(dialog, eListArea, itemType, Handle(theListUPP), &itemRect);
  292.     LDoDraw(true, theList);
  293.     
  294.     /*
  295.      * URL label
  296.      */
  297.     GetDItem(dialog, eURLArea, &itemType, &itemHandle, &itemRect);
  298.     if (theURLUPP == nil)
  299.         theURLUPP = NewUserItemProc(_URLProc);
  300.     SetDItem(dialog, eURLArea, itemType, Handle(theURLUPP), &itemRect);
  301.  
  302.     restoreDialogFont(&saver);
  303. }
  304.  
  305. static short openPrefsFile()
  306. {
  307.     FSSpec spec;
  308.     short vRefNum;
  309.     long parID;
  310.     FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &vRefNum, &parID);
  311.     if (FSMakeFSSpec(vRefNum, parID, "\pApplet Screen Saver Prefs", &spec) == fnfErr) {
  312.         FSpCreateResFile(&spec, 'WARZ', 'PREF', 0);
  313.     }
  314.     return FSpOpenResFile(&spec, fsRdWrPerm);
  315. }
  316.  
  317. static void addToGlobals(Str255 itemLabel, Str255 itemURL)
  318. {
  319.     PtrAndHand(itemLabel, theLabelTexts, 256);
  320.     PtrAndHand(itemURL, theURLTexts, 256);
  321. }
  322.  
  323. static void getGlobals()
  324. {
  325.     short fRefNum = openPrefsFile();
  326.     if (fRefNum != -1) {
  327.         theLabelTexts = GetResource('STNG', 128);
  328.         theURLTexts = GetResource('STNG', 129);
  329.  
  330.         if (theLabelTexts != nil)
  331.             DetachResource(theLabelTexts);
  332.         if (theURLTexts != nil)
  333.             DetachResource(theURLTexts);
  334.     
  335.         Handle hRandom = GetResource('RAND', 128);
  336.         if (hRandom == nil)
  337.             theRandomSet = false;
  338.         else {
  339.             theRandomSet = **hRandom != 0;
  340.             ReleaseResource(hRandom);
  341.         }
  342.         
  343.         Handle hItem = GetResource('SELE', 128);
  344.         if (hItem == nil)
  345.             theCurrentItem = 0;
  346.         else {
  347.             theCurrentItem = *(long*) *hItem;
  348.             ReleaseResource(hItem);
  349.         }
  350.         
  351.         CloseResFile(fRefNum);
  352.     }
  353.  
  354.     if (theLabelTexts == nil || theURLTexts == nil) {
  355.         theLabelTexts = NewHandle(0);
  356.         theURLTexts = NewHandle(0);
  357.  
  358. #if 0
  359.     #define XX(a,b)    \
  360.         addToGlobals("\p" a, "\p" b)
  361.         
  362.         XX("Earthweb's Netris", "http://www.earthweb.com/java/Netris/index.html");
  363.         XX("Rusotto's ZCode Interpreter", "http://www.pond.com/~russotto/zplet/minizork.html");
  364.         XX("HypnoVista Splash", "http://www.hypno.com/javabeta/fromandy/splash/splash.html");
  365.         XX("HypnoVista Bongo Dude", "http://www.hypno.com/javabeta/bongo/bongo.html");
  366.         XX("HypnoVista Running Man", "http://www.hypno.com/javabeta/runner/file.html");
  367.         XX("HypnoVista Hacker", "http://www.hypno.com/javabeta/hacker/file.html");
  368.         XX("HypnoVista Fish", "http://www.hypno.com/javabeta/fish/file.html");
  369.         XX("Circus Animations", "http://circus.compuware.com/");
  370.         XX("At a Distance (Game)", "http://www.cs.cmu.edu/afs/andrew/usr/scier/www/AtADistance.html");
  371.         XX("CERN Accelerator Watch", "http://hpslweb.cern.ch/teletext/java/view110-java.html");
  372.         XX("Sun Golf", "http://www.sun.nl/SunOpenGame/Course1.html");
  373.         XX("Sieve Benchmark", "http://rsb.info.nih.gov/nih-image/Java/Benchmarks/Sieve.html");
  374.         XX("FrogPond", "http://sepwww.stanford.edu/sep/krl/FrogPond/FrogPond.html");
  375.         XX("Bounce Simulator", "http://www.chem.uci.edu/instruction/applets/bounce.html");
  376.         XX("Atmosphere Simulator", "http://www.chem.uci.edu/instruction/applets/canonical.html");
  377. #endif
  378.  
  379.         StringListResource defaultNames(0);
  380.         StringListResource defaultURLs(1);
  381.         
  382.         StringPtr names = defaultNames.First();
  383.         StringPtr urls = defaultURLs.First();
  384.         while (names && urls) {
  385.             addToGlobals(names, urls);
  386.             names = defaultNames.Next();
  387.             urls = defaultURLs.Next();
  388.         }
  389.  
  390.     #undef XX
  391.     }
  392. }
  393.  
  394. static void disposeGlobals()
  395. {
  396.     DisposeHandle(theLabelTexts);
  397.     theLabelTexts = nil;
  398.     DisposeHandle(theURLTexts);
  399.     theURLTexts = nil;
  400.     theList = nil;
  401. }
  402.  
  403. static void setRandomCheckbox(DialogPtr dialog)
  404. {
  405.     short itemType;
  406.     Rect itemRect;
  407.     Handle itemHandle;
  408.     GetDItem(dialog, eRandomCheckbox, &itemType, &itemHandle, &itemRect);
  409.     SetControlValue(ControlHandle(itemHandle), theRandomSet? 1 : 0);
  410. }
  411.  
  412. static void addItems(DialogPtr dialog)
  413. {
  414.     int ctCells = GetHandleSize(theLabelTexts) / sizeof(Str255);
  415.     Cell cell;
  416.     cell.h = 0;
  417.     
  418.     LAddRow(ctCells, -1, theList);
  419.     
  420.     HLock(theLabelTexts);
  421.     char* p = *theLabelTexts;
  422.     for (cell.v = 0;  cell.v < ctCells;  cell.v++) {
  423.         LSetCell(&p[1], p[0], cell, theList);
  424.         p += 256;
  425.     }
  426.  
  427.     setRandomCheckbox(dialog);
  428. }
  429.  
  430. static void updateResource(OSType type, short id, Handle newResource)
  431. {
  432.     Handle hToss = GetResource(type, id);
  433.     if (hToss != nil) {
  434.         RmveResource(hToss);
  435.         DisposeHandle(hToss);
  436.     }
  437.     AddResource(newResource, type, id, "\p");
  438.     WriteResource(newResource);
  439.     DetachResource(newResource);
  440. }
  441.  
  442. static void writeResources()
  443. {
  444.     short fRefNum = openPrefsFile();
  445.     if (fRefNum == -1)
  446.         return;
  447.     updateResource('STNG', 128, theLabelTexts);
  448.     updateResource('STNG', 129, theURLTexts);
  449.     Handle hRandom = NewHandle(1);
  450.     if (hRandom) {
  451.         **hRandom = theRandomSet;
  452.         updateResource('RAND', 128, hRandom);
  453.         DisposeHandle(hRandom);
  454.     }
  455.     Handle hItem = NewHandle(sizeof(long));
  456.     if (hItem) {
  457.         *(long*) *hItem = theCurrentItem;
  458.         updateResource('SELE', 128, hItem);
  459.         DisposeHandle(hItem);
  460.     }
  461.     CloseResFile(fRefNum);
  462. }
  463.  
  464. /*
  465.  * FilterProc
  466.  */
  467.  
  468. static ModalFilterUPP theStdFilterProc;
  469. static ModalFilterUPP theFilterProc = nil;
  470.  
  471. static pascal Boolean _ModalFilter(DialogPtr theDialog, EventRecord *eve, short *itemHit)
  472. {
  473.     Boolean result = false;
  474.     
  475.     *itemHit = -1;
  476.     
  477.     switch (eve->what) {
  478.         case mouseDown: {
  479.             Point localPos = eve->where;
  480.  
  481.             short itemType;
  482.             Rect itemRect;
  483.             Handle itemHandle;
  484.             GetDItem(theDialog, eListArea, &itemType, &itemHandle, &itemRect);
  485.  
  486.             FontSaver saver;
  487.             setupDialogFont(theDialog, 12, &saver);
  488.             
  489.             GlobalToLocal(&localPos);
  490.             if (PtInRect(localPos, &itemRect)) {
  491.                 if (LClick(localPos, eve->modifiers, theList)) {
  492.                     *itemHit = eListArea;
  493.                     result = true;
  494.                 }
  495.                 updateURLArea(theDialog, false);
  496.             }
  497.             
  498.             restoreDialogFont(&saver);
  499.         }    break;
  500.         
  501.         case keyDown: {
  502.             char ch = eve->message & charCodeMask;
  503.             if ((ch == 'c' || ch == 'C' || ch == 'ç' || ch == 'Ç') && (eve->modifiers & cmdKey) != 0) {
  504.                 Str255 itemURL;
  505.                 
  506.                 // if cmd-key, just copy the selected one.  If option, copy all
  507.                 if ((eve->modifiers & optionKey) != 0) {
  508.                     Handle hText = NewHandle(0);
  509.                     int ctItems = GetHandleSize(theURLTexts) / 256;
  510.                     HLock(theURLTexts);
  511.                     char* p = *theURLTexts;
  512.                     for (int i = 0;  i < ctItems;  i++) {
  513.                         PtrAndHand(&p[1], hText, p[0]);
  514.                         PtrAndHand("\r", hText, 1);
  515.                         p += 256;
  516.                     }
  517.                     HUnlock(theURLTexts);
  518.                     HLock(hText);
  519.                     ZeroScrap();
  520.                     PutScrap(GetHandleSize(hText), 'TEXT', *hText);
  521.                     DisposeHandle(hText);
  522.                 } else {
  523.                     getCurrentItem(nil, itemURL);
  524.                     if (itemURL[0] > 0) {
  525.                         ZeroScrap();
  526.                         PutScrap(itemURL[0], 'TEXT', &itemURL[1]);
  527.                     }
  528.                 }
  529.             } else {
  530.                 int newSel = theCurrentItem;
  531.                 
  532.                 result = true;
  533.                 
  534.                 switch (ch) {
  535.                     case 30:    // up
  536.                         newSel--;
  537.                         break;
  538.                         
  539.                     case 31:    // down
  540.                         newSel++;
  541.                         break;
  542.                         
  543.                     case 1:        // home
  544.                         newSel = 0;
  545.                         break;
  546.                         
  547.                     case 4:        // end
  548.                         newSel = (**theList).dataBounds.bottom;                
  549.                         break;
  550.                         
  551.                     case 11: {    // pup
  552.                         Rect* rView = &(**theList).rView;
  553.                         Point pp = (**theList).cellSize;
  554.                         newSel -= ((rView->bottom - rView->top) / pp.v) - 1;
  555.                     }    break;
  556.  
  557.                     case 12: {    // pdown
  558.                         Rect* rView = &(**theList).rView;
  559.                         Point pp = (**theList).cellSize;
  560.                         newSel += ((rView->bottom - rView->top) / pp.v) - 1;
  561.                     }    break;
  562.                 
  563.                     default:
  564.                         result = false;
  565.                 }
  566.  
  567.                 if (result == true) {
  568.                     if (newSel < 0)
  569.                         newSel = 0;
  570.                     if (newSel >= (**theList).dataBounds.bottom)
  571.                         newSel = (**theList).dataBounds.bottom - 1;    
  572.                     if (newSel != theCurrentItem) {
  573.                         FontSaver saver;
  574.                         setupDialogFont(theDialog, 12, &saver);
  575.                 
  576.                         selectItem(newSel);
  577.                         *itemHit = -1;
  578.                         updateURLArea(theDialog, false);
  579.  
  580.                         restoreDialogFont(&saver);
  581.                     }
  582.                 }
  583.             }                
  584.         }    break;
  585.     }
  586.     
  587.     if (result == false && theStdFilterProc != nil)
  588.         result = CallModalFilterProc(theStdFilterProc, theDialog, eve, itemHit);
  589.  
  590.     return result;
  591. }
  592.  
  593. static void hiliteDialogControl(DialogPtr dialog, short ixItem)
  594. {
  595.     short itemType;
  596.     Rect itemRect;
  597.     Handle itemHandle;
  598.     GetDItem(dialog, ixItem, &itemType, &itemHandle, &itemRect);
  599.     HiliteControl(ControlHandle(itemHandle), inButton);
  600.     long actual; Delay(GetDblTime() / 3, &actual);
  601.     HiliteControl(ControlHandle(itemHandle), 0);
  602. }
  603.  
  604. void newAppletDialog()
  605. {
  606.     Str255 itemLabel;
  607.     Str255 itemURL;
  608.     Boolean doRunApplet = nil;
  609.     DialogPtr dialog = GetNewDialog(cAppletDialog, nil, WindowPtr(-1));
  610.     if (dialog) {
  611.         getGlobals();
  612.  
  613.         GetStdFilterProc(&theStdFilterProc);
  614.         if (theFilterProc == nil)
  615.             theFilterProc = NewModalFilterProc(_ModalFilter);
  616.         
  617.         setupUserItems(dialog);
  618.         
  619.         addItems(dialog);
  620.         
  621.         SetDialogDefaultItem(dialog, ok);
  622.         SetDialogCancelItem(dialog, cancel);
  623.         
  624.         short itemHit;
  625.         Boolean continueLoop = true;
  626.         
  627.         selectItem(theCurrentItem);
  628.  
  629.         ShowWindow(dialog);
  630.  
  631.         do {
  632.             ModalDialog(theFilterProc, &itemHit);
  633.             
  634.             switch (itemHit) {
  635.                 case eListArea:
  636.                     hiliteDialogControl(dialog, ok);
  637.                     // fall through
  638.  
  639.                 case ok:
  640.                     if (theCurrentItem != -1) {
  641.                         getCurrentItem(nil, itemURL);
  642.                         doRunApplet = true;
  643.                     }
  644.                     HideWindow(dialog);
  645.                     writeResources();
  646.                     // fall through
  647.                                 
  648.                 case cancel:
  649.                     continueLoop = false;
  650.                     break;
  651.  
  652.                 case eRandomCheckbox:
  653.                     theRandomSet = ! theRandomSet;
  654.                     setRandomCheckbox(dialog);
  655.                     break;
  656.                                     
  657.                 case eAddItem: {
  658.                     itemLabel[0] = 0;
  659.                     itemURL[0] = 0;
  660.                     if (doAddDialog(itemLabel, itemURL)) {
  661.                         addToList(itemLabel, itemURL);
  662.                         updateURLArea(dialog, true);
  663.                     }
  664.                 }    break;
  665.                     
  666.                 case eEditButton: {
  667.                     getCurrentItem(itemLabel, itemURL);
  668.                     if (doAddDialog(itemLabel, itemURL)) {
  669.                         setCurrentItem(dialog, itemLabel, itemURL);
  670.                     }
  671.                 }    break;
  672.                 
  673.                 case eDeleteButton: {
  674.                     deleteCurrentItem(dialog);
  675.                 }    break;
  676.             }
  677.         } while (continueLoop);        
  678.  
  679.         // dispose other user items?        
  680.         LDispose(theList);
  681.  
  682.         DisposeDialog(dialog);
  683.  
  684.         disposeGlobals();
  685.     }
  686. }
  687.  
  688. void getSelectedURL(Str255 urlString, Str255 urlName)
  689. {
  690.     urlString[0] = 0;
  691.     getGlobals();
  692.  
  693.     if (theURLTexts != nil) {
  694.         int ctItems = GetHandleSize(theURLTexts) / 256;
  695.         if (ctItems > 0) {
  696.             int ixSelected;
  697.  
  698.             if (theRandomSet)
  699.                 ixSelected = (Random() & 0x7fff) % ctItems;
  700.             else
  701.                 ixSelected = theCurrentItem;
  702.  
  703.             if (ixSelected < 0)
  704.                 ixSelected = 0;
  705.             if (ixSelected >= ctItems)
  706.                 ixSelected = ctItems - 1;
  707.  
  708.             BlockMoveData(*theLabelTexts + ixSelected * 256, urlName, 256);
  709.             BlockMoveData(*theURLTexts + ixSelected * 256, urlString, 256);
  710.         }
  711.     }
  712.     
  713.     if (urlString[0] == 0) {
  714.         static const unsigned char cDefault[] = "\phttp://www.hypno.com/javabeta/fromandy/splash/splash.html";
  715.         static const unsigned char cDefaultName[] = "\pEmergency default module.";
  716.         BlockMoveData(cDefault, urlString, cDefault[0] + 1);
  717.         BlockMoveData(cDefaultName, urlName, cDefaultName[0] + 1);
  718.     }
  719.  
  720.     disposeGlobals();
  721. }
  722.